package eteam.aps.service.impl;

import cn.hutool.core.bean.BeanUtil;
import eteam.aps.api.U8Api;
import eteam.aps.common.component.LoginUserRedisService;
import eteam.aps.common.entity.ParentEntity;
import eteam.aps.common.exceptions.BusinessException;
import eteam.aps.common.helper.Helper;
import eteam.aps.mapper.*;
import eteam.aps.model.entity.MocoRders;
import eteam.aps.model.entity.MocoRdersBordy;
import eteam.aps.model.entity.ProcessMaterials;
import eteam.aps.model.entity.other.Moco;
import eteam.aps.model.vo.moco_rders.MocoRdersDisplayVo;
import eteam.aps.model.vo.moco_rders.MocoRedersShowVo;
import eteam.aps.model.vo.process_materials.ProcessMaterVo;
import eteam.aps.model.vo.product_number.ProductNumberVo;
import eteam.aps.service.MocoRdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 工单表 业务层 实现类
 *
 * @author LiuLei
 */
@Service
public class MocoRdersServiceImpl implements MocoRdersService {

    @Autowired
    private MocoRdersMapper mocoRdersMapper;

    @Autowired
    private MocoRdersBordyMapper mocoRdersBordyMapper;

    @Autowired
    private ProductNumberMapper productNumber;

    @Autowired
    private ProcessMaterialsMapper processMaterialsMapper;

    @Autowired
    private ProcessMaterialsPreserveMapper processMaterialsPreserveMapper;

    @Autowired
    private LoginUserRedisService loginUserRedisService;

    @Override
    @Transactional
    public MocoRedersShowVo getByMcPn(String mocCode) throws Exception {
        // 创建一个vo对象
        MocoRedersShowVo mocoRedersShowVo = new MocoRedersShowVo();
        Map<String, Object> mc = new HashMap<>(3);
        mc.put("mocCode", Collections.singletonList(mocCode));
        mc.put("fState", ParentEntity.FSTATE_DELETED);
        mc.put("sort", "FMoDId");
        // 查询工单
        List<MocoRders> byMcPn = mocoRdersMapper.getByMcPn(mc);
        // 为空 本地没有 从远程获取任务在
        if (byMcPn.isEmpty()) {
            // 为空没得数据 去U8接口获取数据  并保存在本地
            Moco moco = getDataByU8(mocCode);
            // 赋值
            byMcPn = Collections.singletonList(moco.getMocoRders());
        }
        // 不为空 填充
        mocoRedersShowVo.setMocoRders(byMcPn.stream().map(data -> {
            int qty = productNumber.selectCountByMocCode(ParentEntity.FSTATE_DELETED, data.getfMocCode());
            MocoRdersDisplayVo displayVo = BeanUtil.copyProperties(data, MocoRdersDisplayVo.class);
            displayVo.setfPtsQty(BigDecimal.valueOf(qty));
            displayVo.setfPtsRest(displayVo.getfQty().subtract(displayVo.getfPtsQty()));
            return displayVo;
        }).collect(Collectors.toList()));
        Map<String, Object> pn = new HashMap<>(3);
        pn.put("fState", ParentEntity.FSTATE_DELETED);
        pn.put("fSeqNo", "FSeqNo");
        if (Helper.isNotEmpty(byMcPn.get(0).getfMocCode())) pn.put("mocCode", byMcPn.get(0).getfMocCode());
        // 查询产品序号
        List<ProductNumberVo> pnList = productNumber.selPnListByMoId(pn);
        // 填充
        mocoRedersShowVo.setProductNumbers(pnList);
        return mocoRedersShowVo;
    }

    @Override
    @Transactional
    public List<MocoRdersDisplayVo> getByMcDetauils(String invCode, String mocCode) throws Exception {
        if (Helper.isEmpty(mocCode)) {
            Map<String, Object> map = new HashMap<>(3);
            map.put("fState", ParentEntity.FSTATE_DELETED);
            map.put("invCode", invCode);
            map.put("sort", "FMoDId");
            List<MocoRdersDisplayVo> mocoRdersList = mocoRdersMapper.getByMcInvCode(map);
            if (mocoRdersList.isEmpty()) throw new BusinessException(HttpStatus.BAD_REQUEST, "暂无数据");
            return mocoRdersList;
        } else {
            Map<String, Object> map = new HashMap<>(3);
            map.put("fState", ParentEntity.FSTATE_DELETED);
            map.put("mocCode", mocCode);
            // 根据任务号本地查询
            List<MocoRdersDisplayVo> mocoRedersShowVo = mocoRdersMapper.getByMocoCode(map);
            if (!mocoRedersShowVo.isEmpty()) return mocoRedersShowVo;
            // 本地没有 从接口获取
            Moco moco = getDataByU8(mocCode);
            MocoRders mocoRders = moco.getMocoRders();
            return Collections.singletonList(BeanUtil.copyProperties(mocoRders, MocoRdersDisplayVo.class));
        }
    }

    @Override
    @Transactional
    public List<MocoRdersDisplayVo> getByMc(String mocCode) throws Exception {
        Map<String, Object> mc = new HashMap<>(3);
        mc.put("mocCode", Collections.singletonList(mocCode));
        mc.put("fState", ParentEntity.FSTATE_DELETED);
        mc.put("sort", "FMoDId");
        // 查询工单
        List<MocoRders> byMcPn = mocoRdersMapper.getByMcPn(mc);
        // 为空 本地没有 从远程获取任务
        if (byMcPn.isEmpty()) {
            // 为空没得数据 去U8接口获取数据  并保存在本地
            Moco moco = getDataByU8(mocCode);
            // 赋值
            byMcPn = Collections.singletonList(moco.getMocoRders());
        }
        return byMcPn.stream().map(data -> BeanUtil.copyProperties(data, MocoRdersDisplayVo.class)).collect(Collectors.toList());
    }

    /**
     * 获取 U8数据
     *
     * @param mocCode 任务令
     * @return
     * @throws Exception
     */
    @Transactional
    public Moco getDataByU8(String mocCode) throws Exception {
        // 从U8接口获取 工单信息
        Moco moco = U8Api.getMocoByCondition(mocCode);
        // 事务失效
        if (Helper.checkObjAllFieldsIsNull(moco)) throw new BusinessException(HttpStatus.BAD_REQUEST, "暂无数据！");
        // 工单
        MocoRders mocoRders = moco.getMocoRders();
        // 工单物料
        List<MocoRdersBordy> mocoRdersBordyList = moco.getMocoRdersBordyList();
        List<ProcessMaterials> lis = new LinkedList<>();
        // 工单预计产量
//        BigDecimal qty = mocoRders.getfQty();
        String fuserid = loginUserRedisService.getUser().fuserid;
        for (MocoRdersBordy data : mocoRdersBordyList) {
            ProcessMaterials processMaterials = new ProcessMaterials(mocoRders.getfMocCode(), // 任务令
                    data.getfSortSeq(), // 序号
                    data.getfInvCode(), // 物料编号
                    data.getfInvName(), // 物料名称
                    data.getfStdRemark(), // 物料型号
                    null, // 扫描工序
                    null, // 工序名称
//                    data.getfQty().divide(qty, 4).toString() //【工单预计产量/物料产量】单套数量
                    data.getfBaseQtyN().toString());
            Helper.setDefaultAddValue(processMaterials, fuserid);
            lis.add(processMaterials);
        }
        Map<String, Object> map = new HashMap<>(2);
        map.put("fState", ParentEntity.FSTATE_DELETED);
        map.put("invCode", mocoRders.getfInvCode());
        map.put("proName", "FProName");
        map.put("scaPro", "FScaPro");
        // 查询出产品 工艺维维护信息
        List<ProcessMaterVo> processMaterVoList = processMaterialsPreserveMapper.selPmpByPreserve(map);
        if (!processMaterVoList.isEmpty()) {
            // 根据工序维护的  物料编号分组
            Map<String, ProcessMaterials> p = new HashMap<>(lis.size());
            for (ProcessMaterials materials : lis) p.put(materials.getfInvCode(), materials);
            // 将产品工序的规范 修改到 任务工序
            for (ProcessMaterVo vo : processMaterVoList) {
                ProcessMaterials materials = p.get(vo.getfInvCode());
                if (materials != null) {
                    materials.setfProName(vo.getfProName());
                    materials.setfScaPro(vo.getfScaPro());
                }
            }
        }
        // 批量添加 工单信息 物料信息 产品工序信息
        savaU8Data(mocoRders, mocoRdersBordyList, lis);
        return moco;
    }


    /**
     * U8 接口数据保存
     *
     * @param mocoRders          工单
     * @param mocoRdersBordyList 工单物料
     * @param lis                工单工序
     * @return 是否修改成功
     */
    @Transactional
    public boolean savaU8Data(MocoRders mocoRders, List<MocoRdersBordy> mocoRdersBordyList, List<ProcessMaterials> lis) {
        if (mocoRders != null) mocoRdersMapper.batchSave(Collections.singletonList(mocoRders));
        if (!mocoRdersBordyList.isEmpty()) mocoRdersBordyMapper.batchSave(mocoRdersBordyList);
        if (!lis.isEmpty()) processMaterialsMapper.batchSaveProcessMaterials(lis);
        return true;
    }


}
